#include "BaseType.h"
#include "Tracer.h"
using namespace std;
using namespace libemb;

/**
 * 观察者模式：
 * 1.主题和观察者是一对多的关系
 * 2.当主题发生改变时，所有依赖主题的观察者都能得到通知
 * 3.主题和观察者之间解耦,扩展一个类不会影响到另一个类。
 * 适用场景：
 * 1.两个类的对象之间存在依赖关系，一个类对象的改变会引起另一个类的多个对象产生反应
 * 2.软件定时器、输入事件监听器等场景
 **/

//观察者
class Observer{
DECL_CLASSNAME(Observer)
public:
    virtual void read(std::string topic)=0;
};

class Student: public Observer{
DECL_CLASSNAME(Student)
public:
    void read(std::string topic) override
    {
        TRACE_INFO_CLASS("student read topic: %s",CSTR(topic));
    }
};

class Teacher: public Observer{
DECL_CLASSNAME(Teacher)
public:
    void read(std::string topic) override
    {
        TRACE_INFO_CLASS("teacher read topic: %s",CSTR(topic));
    }
};

//主题
class Subject{
DECL_CLASSNAME(Subject)
private:
    std::map<std::string,std::shared_ptr<Observer>> m_observers;
public:
    void addObserver(std::string name, std::shared_ptr<Observer> observer)
    {
        m_observers.insert({name,observer});
    }
    void delObserver(std::string name)
    {
        m_observers.erase(name);
    }

    //发布消息
    void publish(std::string topic)
    {
        for(auto observer: m_observers)
        {
            observer.second->read(topic);
        }
    }
};


int main()
{
    Tracer::getInstance().setLevel(TRACE_LEVEL_DBG);
	Tracer::getInstance().addSink(std::make_shared<STDSink>()).start();

    Subject subject;
    auto student = std::make_shared<Student>();
    auto teacher = std::make_shared<Teacher>();
    subject.addObserver("student",student);
    subject.addObserver("teacher",teacher);
    subject.publish("Big News");
    return RC_OK;
}